package org.jiucheng.magpiebridge.manager.handler;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;

//import org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException;
import org.jiucheng.aop.AopException;
import org.jiucheng.ioc.BeanFactory;
import org.jiucheng.ioc.annotation.Impl;
import org.jiucheng.ioc.annotation.Inject;
import org.jiucheng.magpiebridge.manager.MangagerException;
import org.jiucheng.magpiebridge.manager.dto.openapi.v1.Openapi;
import org.jiucheng.magpiebridge.manager.out.OpenapiOut;
import org.jiucheng.magpiebridge.manager.util.JwtUtil;
import org.jiucheng.magpiebridge.manager.util.ThreadArgs;
import org.jiucheng.orm.DataAccessException;
import org.jiucheng.web.WebWrapper;
import org.jiucheng.web.handler.Out;
import org.jiucheng.web.util.WebUtil;

public class OpenapiHandler extends UncheckOpenapiHandler {
    
    @Inject
    private JwtUtil jwtUtil;
    @Impl(OpenapiOut.class)
    private Out out;
    
    @Override
    public boolean before(WebWrapper webWrapper) throws ServletException {
        Cookie[] cookies = WebUtil.getRequest().getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("token".equals(cookie.getName())) {
                    String token = cookie.getValue();
                    try {
                        Map<String, String> claims = jwtUtil.verifyToken(token);
                        Long gid = Long.parseLong(claims.get("gid"));
                        ThreadArgs.setGid(gid);
                        ThreadArgs.setGemail(claims.get("gemail"));
                        ThreadArgs.setIsSuper(claims.get("isSuper"));
                        return true;
                    } catch (Exception e) {
                        // e.printStackTrace();
                        break;
                    }
                }
            }
        }
        out.invoke(webWrapper, Openapi.newInstance(-1, "非法请求"));
        return false;
    }
    
    public void invoke(WebWrapper webWrapper) throws ServletException {
        Object ctrl = BeanFactory.get(webWrapper.getCtrl().getBeanName());
        Method method = webWrapper.getCtrl().getMethod();
        method.setAccessible(true);
        
        Out out = BeanFactory.getInstance(webWrapper.getCtrl().getRequestMapping().out());
        try {
            Object obj = method.invoke(ctrl, getArgs(method, webWrapper).toArray());
            out.invoke(webWrapper, obj);
        } catch (IllegalAccessException e) {
            throw new ServletException(e);
        } catch (IllegalArgumentException e) {
            throw new ServletException(e);
        } catch (InvocationTargetException e) {
            Throwable t;
            if (e instanceof InvocationTargetException) {
                t = ((InvocationTargetException) e).getTargetException();
            } else {
                t = e;
            }
            if (t instanceof AopException) {
            	t = ((AopException) t).getCause();
            }
            if (t instanceof DataAccessException) {
            	t = ((DataAccessException) t).getCause();
            }
            if (t instanceof MangagerException) {
            	MangagerException me = (MangagerException) t;
            	out.invoke(webWrapper, Openapi.newInstance(me.getCode(), me.getMessage()));
            } /*else if (t instanceof JdbcSQLIntegrityConstraintViolationException) {
            	out.invoke(webWrapper, Openapi.newInstance(10001, "操作失败，已存在~"));
            } */else {
            	throw new ServletException(t);
            }
        }
    }
}
